/*
 * @(#)Controller.java 0.0.1-SNAPSHOT
 *
 * Copyright Group B
 */

package grupb.upf.Controller.impl;

import grupb.upf.DBManager.DBAction;
import grupb.upf.DBManager.DBActionResult;
import grupb.upf.DBManager.DBManager;
import grupb.upf.XMLObjects.Author;
import grupb.upf.XMLObjects.New;
import grupb.upf.XMLObjects.Photo;
import grupb.upf.XMLObjects.PhotoNew;
import grupb.upf.XMLObjects.Video;
import grupb.upf.XMLObjects.impl.PersonalTag;
import grupb.upf.XMLObjects.impl.PredefinedTag;
import grupb.upf.gui.P2Piki;
import grupb.upf.ms.Content;
import grupb.upf.ms.DescriptionContent;
import grupb.upf.ms.InstantMessage;
import grupb.upf.ms.SearchProfile;
import grupb.upf.ms.SearchResult;
import grupb.upf.ms.UserContent;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import javax.swing.ImageIcon;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>This class implements the interface Controller and it is used
 * to coordinate the GUI with the Messaging System.</p>
 *
 * @version    0.0.1-SNAPSHOT
 * @author     Group B
 */
public final class Controller implements
        grupb.upf.Controller.Controller {

    /**
     * The logger. A new logger <code>grupb.upf.configuration.Controller</code>
     * is created to add the logs of this Controller.
     */
    private static final Log LOG = LogFactory.getLog(Controller.class);
    /**
     * The GUI to send the changes.
     */
    private P2Piki p2p;
    /**
     * The class which receive and send messages by the network.
     */
    private InstantMessage im;
    /**
     * Constructor of the class
     */
    public Controller() {
        try {
            new grupb.upf.util.Config();
        } catch (IOException ex) {
            if (LOG.isFatalEnabled()) {
                LOG.fatal("Fatal error loading the configuration", ex);
            }
        }
        p2p = new P2Piki(this);
        p2p.setVisible(true);
        im = new grupb.upf.ms.impl.InstantMessage(this);
    }
    /**
     * This method allows us to connect and identif icate to GoogleTalk.
     * @param aLogin is the userName of the Google Account (account@gmail.com)
     * @param aPassword is the password of the Google Account
     * @param resource is the resource, usually "Home"
     * @return boolean (true if it has logged and false if not)
     */
    @Override
    public boolean login(final String aLogin, final String aPassword,
            final String resource) {
        return im.login(aLogin, aPassword, resource);
    }
    /**
     * Method to logout.
     */
    @Override
    public void logout() {
        im.logout();
    }
    /**
     * Method to notice the database that the state of the connection.
     * @param state the state of the connection
     * @return true if it was successful or false if not.
     */
    @Override
    public void connectionState(final boolean state) {
        p2p.connectionState(state);
    }
    /**
     * Method to send an error to the GUI.
     * @param err the error
     */
    @Override
    public void addError(final String err) {
        p2p.addError(err);
    }
    /**
     * Method to add a connected friend.
     * @param friend the username and resource of the friend
     */
    @Override
    public void addFriend(final String friend) {
        p2p.addFriend(friend);
    }
    /**
     * Method to delete a friend.
     * @param friend the username and resource of the disconnected friend
     */
    @Override
    public void removeFriend(final String friend) {
        p2p.removeFriend(friend);
    }
    /**
     * Method to remove all the friends.
     */
    @Override
    public void removeFriends() {
        p2p.removeFriends();
    }
    /**
     * This method allows us to send a SearchProfile to a concrete user.
     * @param sp the object SearchProfile which we are looking for
     * @param to the receiver of the searchProfile message
     */
    @Override
    public void sendSearchProfile(final SearchProfile sp, final String to) {
        im.sendSearchProfile(sp, to);
    }
    /**
     * This method allows us to send a SearchProfile to all the connected
     * users.
     * @param sp the object SearchProfile which we are looking for
     */
    @Override
    public void sendSearchProfile(final SearchProfile sp) {
        im.sendSearchProfile(sp);
    }
    /**
     * Method to notice the GUI that result of the search has been received.
     * @param dc the DescriptionContent of the result received
     */
    @Override
    public void searchResultReceived(final DescriptionContent dc) {
        p2p.addResult(dc);
    }
    /**
     * Method to send a SearchResult.
     * @param sr the search result to be sent
     * @param to the opponent
     */
    @Override
    public void sendSearchResult(final SearchResult sr, final String to) {
        im.sendSearchResult(sr, to);
    }
    @Override
    public void sendUserContent(final UserContent uc, final String to) {
        im.sendUserContent(uc, to);
    }
    /**
     * Method to notice the GUI that a content has been received.
     * @param c the Content received
     */
    @Override
    public void contentReceived(final Content c) {
        p2p.contentReceived(c);
    }
    /**
     * Method to notice the GUI that a chat message has been received.
     * @param message the message
     * @param from the opponent
     */
    @Override
    public void chatMessageReceived(final String message, final String from) {
        p2p.chatMessageReceived(message, from);
    }
    /**
     * Method to send a chat message to all the connected people.
     * @param msg the message to send
     */
    @Override
    public void sendChatMessage(final String msg) {
        im.sendChatMessage(msg);
    }
    /**
     * Method to notice the GUI that a chat message has been received.
     * @param message the message
     * @param from the opponent
     */
    @Override
    public void instantMessageReceived(final String message,
            final String from) {
        p2p.instantMessageReceived(message, from);
    }
    /**
     * Method to send an instant message to another user.
     * @param msg the message
     * @param to the opponent
     */
    @Override
    public void sendInstantMessage(final String msg, final String to) {
        im.sendInstantMessage(msg, to);
    }
    /**
     * Method to do a localSearch.
     * @param des the DescriptionContent of the searched objects
     */
    @Override
    public void localSearch(final DescriptionContent des) {
        search(des, "me");
    }
    /**
     * Method to do a localSearch.
     * @param des the DescriptionContent of the searched objects
     * @param from the opponent, who has sent the SearchProfile
     */
    @Override
    public void networkSearch(final DescriptionContent des, final String from) {
        search(des, from);
    }
    /**
     * Method to get the ontology categories.
     */
    @Override
    public List getTaxonomies() {
        //Creamos la nueva action
        DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                "query.taxonomies", null);
        //Pedimos una instancia para hacer la query
        DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        DBActionResult actionResult = dbm.execute(dba);
        //Ya tenemos los resultados
        return actionResult.getResult();
    }
    /**
     * Method to search an object.
     * @param from who is searching, if it is "me" it is a local search.
     * @param des the DescriptionContent which contains the description of the
     * searched object.
     */
    public void search(final DescriptionContent des, final String from) {
        DescriptionContent dc = des;
        //Creamos la nueva action
        DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                (String) dc.getProperty("key"), (Object[])
                dc.getProperty("parameters"));
        //Pedimos una instancia para hacer la query
        DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        DBActionResult actionResult = dbm.execute(dba);
        //Ya tenemos los resultados
        List res = actionResult.getResult();

        if (LOG.isInfoEnabled()) {
            final StringBuffer sb = new StringBuffer("Results: ")
                    .append(res.size());
            LOG.info(sb);
        }
        for (int i = 0; i < res.size(); i++) {
            boolean isOk = true;
            dc = new grupb.upf.ms.impl.DescriptionContent();
            if (res.get(i) instanceof Photo) {
                StringBuffer sb = new StringBuffer(
                        grupb.upf.util.Config.getProperty("photo.folder"))
                        .append(((Photo) res.get(i)).getURL());
                final String url = sb.toString();
                final File file = new File(url);
                isOk = false;
                if (LOG.isInfoEnabled()) {
                    sb = new StringBuffer("The image: ")
                            .append(url).append(" exists: ")
                            .append(file.exists());
                    LOG.info(sb);
                }
                if (file.exists()) {
                    isOk = true;
                    final ImageIcon thumbnail =
                            grupb.upf.imageProcessing
                            .Thumbnail.getThumbnail(url);
                    dc.addProperty("thumbnail", thumbnail);
                }
            } else if (res.get(i) instanceof New) {
                final List bodyElements = ((New) res.get(i))
                        .getBody().getElements();
                for (int j = 0; j < bodyElements.size(); j++) {
                    if (bodyElements.get(j) instanceof PhotoNew) {
                        StringBuffer sb = new StringBuffer(
                        grupb.upf.util.Config.getProperty("photo.folder"))
                        .append(((PhotoNew) bodyElements.get(j)).getUrl());
                        String url = sb.toString();
                        ImageIcon icon = grupb.upf.imageProcessing
                            .Thumbnail.getThumbnail(url);
                        if (icon != null) {
                            ((PhotoNew) bodyElements.get(j)).setIcon(icon);
                        }
                    }
                }
            }
            if (isOk) {
                dc.addProperty("properties", res.get(i));
                dc.addProperty("from", from);
                if (from.equalsIgnoreCase("me")) {
                    searchResultReceived(dc);
                } else {
                    if (grupb.upf.util
                            .Config.getProperty("ip") != null ||
                            grupb.upf.util
                            .Config.getProperty("vlc.folder") != null) {
                        dc.addProperty("ip", grupb.upf.util
                                .Config.getProperty("ip"));
                        final SearchResult sr =
                                new grupb.upf.ms.impl.SearchResult(dc);
                        sendSearchResult(sr, from);
                    } else {
                        if (LOG.isErrorEnabled()) {
                            LOG.error("We don't send the video information because we don't have configured to send it by RTP (our VLC or IP).");
                        }
                    }
                }
            }
        }
    }
    /**
     * Method to add a photo to the DB.
     * @param p the photo to be added
     */
    @Override
    public boolean addPhoto(final Photo p) {
        boolean flag = true;
        String action = "insert.photo";
        final Object [] params = new Object[12];
        params[11] = p.getURL();
        params[0] = p.getMetadataDC().getContentProperty("dc.title");
        params[1] = p.getMetadataDC().getContentProperty("dc.subject");
        params[2] = p.getMetadataDC().getContentProperty("dc.description");
        params[3] = p.getMetadataDC().getContentProperty("dc.source");
        params[4] = p.getMetadataDC().getIntellectualProperty("dc.creator");
        params[5] = p.getMetadataDC().getIntellectualProperty("dc.publisher");
        params[6] = p.getMetadataDC().getIntellectualProperty("dc.contributor");
        params[7] = p.getMetadataDC().getIntellectualProperty("dc.rights");
        final Calendar cal = Calendar.getInstance();
        final int thisYear = cal.get(Calendar.YEAR);
        final int thisMonth = cal.get(Calendar.MONTH) + 1;
        final int today = cal.get(Calendar.DATE);
        params[8] = thisYear * 10000 + thisMonth * 100 + today;
        //format
        final int formatIndex = p.getURL().lastIndexOf(".") + 1;
        params[9] = p.getURL().substring(formatIndex);
        //language
        params[10] = "English";
        if (LOG.isInfoEnabled()) {
            LOG.info(action);
        }
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, params);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        if (!actionResult.isOk()) {
            final StringBuffer err = new StringBuffer(
                "Error inserting the image to the DB");
            flag = false;
            err.append("\n");
            if (actionResult.getErrorMsg() != null) {
                err.append(actionResult.getErrorMsg());
            } else {
                err.append(actionResult.getException());
            }
            if (LOG.isErrorEnabled()) {
                LOG.error(err);
            }
        } else {
            p.setID(getId(p.getURL(), "photo"));
            if (p.getID() != -1) {
                flag = insertPhotoTags(p);
            }
        }
        return flag;
    }
    /**
     * Method to update a photo to the DB.
     * @param p the photo to be updated
     */
    @Override
    public boolean updatePhoto(final Photo p) {
        boolean flag = true;
        String action = "update.photo";
        final Object [] params = new Object[9];
        params[8] = p.getID();
        params[0] = p.getMetadataDC().getContentProperty("dc.title");
        params[1] = p.getMetadataDC().getContentProperty("dc.subject");
        params[2] = p.getMetadataDC().getContentProperty("dc.description");
        params[3] = p.getMetadataDC().getContentProperty("dc.source");
        params[4] = p.getMetadataDC().getIntellectualProperty("dc.creator");
        params[5] = p.getMetadataDC().getIntellectualProperty("dc.publisher");
        params[6] = p.getMetadataDC().getIntellectualProperty("dc.contributor");
        params[7] = p.getMetadataDC().getIntellectualProperty("dc.rights");
        if (LOG.isInfoEnabled()) {
            LOG.info(action);
        }
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, params);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        if (!actionResult.isOk()) {
            final StringBuffer err = new StringBuffer(
                "Error updating the image.");
            flag = false;
            err.append("\n");
            if (actionResult.getErrorMsg() != null) {
                err.append(actionResult.getErrorMsg());
            } else {
                err.append(actionResult.getException());
            }
            if (LOG.isErrorEnabled()) {
                LOG.error(err);
            }
        } else {
            if (p.getID() != -1) {
                flag = insertPhotoTags(p);
            }
        }
        return flag;
    }
    /**
     * Method to delete a photo from the DB.
     * @param id the id of the photo to be deleted
     */
    @Override
    public boolean deletePhoto(final int id) {
        boolean flag = true;
        final Object[] param = new Object[1];
        param[0] = id;
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                "delete.photo", param);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager
                .getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        //Ya tenemos los resultados
        if (actionResult.isOk()) {
            if (LOG.isInfoEnabled()) {
                LOG.info("Photo deleted correctly.");
            }
        } else {
            if (LOG.isErrorEnabled()) {
                LOG.error("Error deleting the photo from the DB.");
            }
            flag = false;
        }
        return flag;
    }
    /**
     * Method to get a photo from the DB.
     * @param url the url of the photo
     * @return the photo
     */
    @Override
    public Photo getPhoto(final String url) {
        Object[] param = new Object[1];
        param[0] = url;
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                "query.photo.url", param);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        //Ya tenemos los resultados
        final List res = actionResult.getResult();
        if (actionResult.isOk()) {
            if (res != null && res.size() > 0) {
                return (Photo) res.get(0);
            }
        }
        return null;
    }
    /**
     * Method to add a video to the DB.
     * @param v the video to be added
     */
    @Override
    public boolean addVideo(final Video v) {
        boolean flag = true;
        String action = "insert.video";
        final Object [] params = new Object[12];
        params[11] = v.getURL();
        params[0] = v.getMetadataDC().getContentProperty("dc.title");
        params[1] = v.getMetadataDC().getContentProperty("dc.subject");
        params[2] = v.getMetadataDC().getContentProperty("dc.description");
        params[3] = v.getMetadataDC().getContentProperty("dc.source");
        params[4] = v.getMetadataDC().getIntellectualProperty("dc.creator");
        params[5] = v.getMetadataDC().getIntellectualProperty("dc.publisher");
        params[6] = v.getMetadataDC().getIntellectualProperty("dc.contributor");
        params[7] = v.getMetadataDC().getIntellectualProperty("dc.rights");
        final Calendar cal = Calendar.getInstance();
        final int thisYear = cal.get(Calendar.YEAR);
        final int thisMonth = cal.get(Calendar.MONTH) + 1;
        final int today = cal.get(Calendar.DATE);
        params[8] = thisYear * 10000 + thisMonth * 100 + today;
        //format
        final int formatIndex = v.getURL().lastIndexOf(".") + 1;
        params[9] = v.getURL().substring(formatIndex);
        //language
        params[10] = "English";
        if (LOG.isInfoEnabled()) {
            LOG.info(action);
        }
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, params);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        if (!actionResult.isOk()) {
            final StringBuffer err = new StringBuffer(
                "Error inserting the video to the DB");
            flag = false;
            err.append("\n");
            if (actionResult.getErrorMsg() != null) {
                err.append(actionResult.getErrorMsg());
            } else {
                err.append(actionResult.getException());
            }
            if (LOG.isErrorEnabled()) {
                LOG.error(err);
            }
        } else {
            v.setID(getId(v.getURL(), "video"));
            if (v.getID() != -1) {
                flag = insertVideoTags(v);
            }
        }
        return flag;
    }
    /**
     * Method to update a video to the DB.
     * @param p the video to be updated
     */
    @Override
    public boolean updateVideo(final Video v) {
        boolean flag = true;
        String action = "update.video";
        final Object [] params = new Object[9];
        params[8] = v.getID();
        params[0] = v.getMetadataDC().getContentProperty("dc.title");
        params[1] = v.getMetadataDC().getContentProperty("dc.subject");
        params[2] = v.getMetadataDC().getContentProperty("dc.description");
        params[3] = v.getMetadataDC().getContentProperty("dc.source");
        params[4] = v.getMetadataDC().getIntellectualProperty("dc.creator");
        params[5] = v.getMetadataDC().getIntellectualProperty("dc.publisher");
        params[6] = v.getMetadataDC().getIntellectualProperty("dc.contributor");
        params[7] = v.getMetadataDC().getIntellectualProperty("dc.rights");
        if (LOG.isInfoEnabled()) {
            LOG.info(action);
        }
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, params);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        if (!actionResult.isOk()) {
            final StringBuffer err = new StringBuffer(
                "Error updating the video");
            flag = false;
            err.append("\n");
            if (actionResult.getErrorMsg() != null) {
                err.append(actionResult.getErrorMsg());
            } else {
                err.append(actionResult.getException());
            }
            if (LOG.isErrorEnabled()) {
                LOG.error(err);
            }
        } else {
            if (v.getID() != -1) {
                flag = insertVideoTags(v);
            }
        }
        return flag;
    }
    /**
     * Method to delete a video from the DB.
     * @param id the id of the video to be deleted
     */
    @Override
    public boolean deleteVideo(final int id) {
        boolean flag = true;
        final Object[] param = new Object[1];
        param[0] = id;
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                "delete.video", param);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager
                .getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        //Ya tenemos los resultados
        if (actionResult.isOk()) {
            if (LOG.isInfoEnabled()) {
                LOG.info("Video deleted correctly.");
            }
        } else {
            if (LOG.isErrorEnabled()) {
                LOG.error("Error deleting the video from the DB.");
            }
            flag = false;
        }
        return flag;
    }
    /**
     * Method to get a video from the DB.
     * @param url the url of the video
     * @return the video
     */
    @Override
    public Video getVideo(final String url) {
        Object[] param = new Object[1];
        param[0] = url;
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                "query.video.url", param);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        //Ya tenemos los resultados
        final List res = actionResult.getResult();
        if (actionResult.isOk()) {
            if (res != null && res.size() > 0) {
                return (Video) res.get(0);
            }
        }
        return null;
    }
    /**
     * Method to add a new to the DB.
     * @param nw the new to be added
     */
    @Override
    public boolean addNew(final New nw) {
        boolean flag = true;
        String action = "insert.new";
        final Object [] params = new Object[5];
        params[0] = nw.getTitle();
        params[1] = nw.getSubtitle();
        params[2] = nw.getSource();
        final Calendar cal = Calendar.getInstance();
        final int thisYear = cal.get(Calendar.YEAR);
        final int thisMonth = cal.get(Calendar.MONTH) + 1;
        final int today = cal.get(Calendar.DATE);
        params[3] = thisYear * 10000 + thisMonth * 100 + today;
        final List e = nw.getBody().getElements();
        params[4] = (String) e.get(0);
        if (LOG.isInfoEnabled()) {
            LOG.info(action);
        }
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, params);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        if (!actionResult.isOk()) {
            final StringBuffer err = new StringBuffer(
                "Error inserting the new to the DB");
            flag = false;
            err.append("\n");
            if (actionResult.getErrorMsg() != null) {
                err.append(actionResult.getErrorMsg());
            } else {
                err.append(actionResult.getException());
            }
            if (LOG.isErrorEnabled()) {
                LOG.error(err);
            }
        } else {
            nw.setID(getLastNewId());
            if (nw.getID() != -1) {
                flag = insertNewTags(nw);
                flag &= insertNewAuthors(nw);
            }
        }
        return flag;
    }
    /**
     * Method to update a new to the DB.
     * @param nw the new to be updated
     */
    @Override
    public boolean updateNew(final New nw) {
        boolean flag = true;
        String action = "update.new";
        final Object [] params = new Object[5];
        params[3] = nw.getID();
        params[0] = nw.getTitle();
        params[1] = nw.getSubtitle();
        params[2] = nw.getSource();
        final List e = nw.getBody().getElements();
        params[4] = (String) e.get(0);
        if (LOG.isInfoEnabled()) {
            LOG.info(action);
        }
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, params);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        if (!actionResult.isOk()) {
            final StringBuffer err = new StringBuffer(
                "Error updating the new");
            flag = false;
            err.append("\n");
            if (actionResult.getErrorMsg() != null) {
                err.append(actionResult.getErrorMsg());
            } else {
                err.append(actionResult.getException());
            }
            if (LOG.isErrorEnabled()) {
                LOG.error(err);
            }
        } else {
            if (nw.getID() != -1) {
                flag = insertNewTags(nw);
                flag &= insertNewAuthors(nw);
            }
        }
        return flag;
    }
    /**
     * Method to delete a new from the DB.
     * @param id the id of the new to be deleted
     */
    @Override
    public boolean deleteNew(final int id) {
        boolean flag = true;
        final Object[] param = new Object[1];
        param[0] = id;
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                "delete.new", param);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager
                .getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        //Ya tenemos los resultados
        if (actionResult.isOk()) {
            if (LOG.isInfoEnabled()) {
                LOG.info("New deleted correctly.");
            }
        } else {
            if (LOG.isErrorEnabled()) {
                LOG.error("Error deleting the new from the DB.");
            }
            flag = false;
        }
        return flag;
    }
    /**
     * Method to get the list of news.
     * @return the list of news
     */
    @Override
    public List getNews() {
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                "query.new", null);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        //Ya tenemos los resultados
        final List res = actionResult.getResult();
        if (actionResult.isOk()) {
            return res;
        }
        return null;
    }
    /**
     * Method to get the id of a object.
     * @param url the URL of the object
     * @param type photo or video
     * @return the ID of the photo
     */
    private int getId(final String url, final String type) {
        final Object[] params = {url};
        if (LOG.isInfoEnabled()) {
            final StringBuffer sb = new StringBuffer(
                    "We try to get the Id of the photo: ")
                    .append(url);
            LOG.info(sb);
        }
        final String action = "query.id." + type;
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, params);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        if (actionResult.isOk()) {
            List res = actionResult.getResult();
            if (res != null && res.size() > 0) {
                if (LOG.isInfoEnabled()) {
                    StringBuffer sb = new StringBuffer("We have the ID: ");
                    sb.append(Integer.parseInt((String) res.get(0)));
                    LOG.info(sb);
                }
                return Integer.parseInt((String) res.get(0));
            }
        }
        return -1;
    }
    /**
     * Method to get the id of the last new added.
     * @return the ID of the new
     */
    private int getLastNewId() {
        final String action = "query.id.new.last";
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, null);
        //Pedimos una instancia para hacer la query
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager.getInstance();
        final DBActionResult actionResult = dbm.execute(dba);
        if (actionResult.isOk()) {
            List res = actionResult.getResult();
            if (res != null && res.size() > 0) {
                if (LOG.isInfoEnabled()) {
                    StringBuffer sb = new StringBuffer("We have the ID: ");
                    sb.append(Integer.parseInt((String) res.get(0)));
                    LOG.info(sb);
                }
                return Integer.parseInt((String) res.get(0));
            }
        }
        return -1;
    }
    /**
     * Method to insert the tags of a photo.0
     * @param p the photo data
     * @return true or false
     */
    private boolean insertPhotoTags(final Photo p) {
        boolean flag = true;
        String action = "";
        final List personalTags = p.getTags().getPersonalTags();
        final List predefinedTags = p.getTags().getPredefinedTags();
        for (int i = 0; i < personalTags.size(); i++) {
            Object[] parameters = null;
            final PersonalTag tag = (PersonalTag) personalTags.get(i);
            if (tag.getCoordenates() != null) {
                action = "insert.photo.personaltag.coordenates";
                parameters = new Object[6];
                parameters[2] = (Integer) tag.getCoordenates()
                        .get("x1");
                parameters[3] = (Integer) tag.getCoordenates()
                        .get("x2");
                parameters[4] = (Integer) tag.getCoordenates()
                        .get("y1");
                parameters[5] = (Integer) tag.getCoordenates()
                        .get("y2");
            } else {
                action = "insert.photo.personaltag";
                parameters = new Object[2];
            }
            parameters[0] = p.getID();
            parameters[1] = tag.getTag();
            flag &= insertTag(action, parameters);
        }
        for (int i = 0; i < predefinedTags.size(); i++) {
            Object[] parameters = null;
            final PredefinedTag tag = (PredefinedTag) predefinedTags.get(i);
            if (tag.getCoordenates() != null) {
                action = "insert.photo.ontologytag.coordenates";
                parameters = new Object[7];
                parameters[2] = (Integer) tag.getCoordenates()
                        .get("x1");
                parameters[3] = (Integer) tag.getCoordenates()
                        .get("x2");
                parameters[4] = (Integer) tag.getCoordenates()
                        .get("y1");
                parameters[5] = (Integer) tag.getCoordenates()
                        .get("y2");
                parameters[6] = tag.getCategory();
            } else {
                action = "insert.photo.ontologytag";
                parameters = new Object[3];
                parameters[2] = tag.getCategory();
            }
            parameters[0] = p.getID();
            parameters[1] = tag.getTag();
            flag &= insertTag(action, parameters);
        }
        return flag;
    }
    /**
     * Method to insert the tags of a video
     * @param v the video data
     * @return true or false
     */
    private boolean insertVideoTags(final Video v) {
        boolean flag = true;
        String action = "";
        final List personalTags = v.getTags().getPersonalTags();
        final List predefinedTags = v.getTags().getPredefinedTags();
        for (int i = 0; i < personalTags.size(); i++) {
            Object[] parameters = null;
            final PersonalTag tag = (PersonalTag) personalTags.get(i);
            action = "insert.video.personaltag";
            parameters = new Object[2];
            parameters[0] = v.getID();
            parameters[1] = tag.getTag();
            flag &= insertTag(action, parameters);
        }
        for (int i = 0; i < predefinedTags.size(); i++) {
            Object[] parameters = null;
            final PredefinedTag tag = (PredefinedTag) predefinedTags.get(i);
            action = "insert.video.ontologytag";
            parameters = new Object[3];
            parameters[2] = tag.getCategory();
            parameters[0] = v.getID();
            parameters[1] = tag.getTag();
            flag &= insertTag(action, parameters);
        }
        return flag;
    }
    /**
     * Method to insert the tags of a new
     * @param nw the new data
     * @return true or false
     */
    private boolean insertNewTags(final New nw) {
        boolean flag = true;
        String action = "";
        final List personalTags = nw.getTags().getPersonalTags();
        final List predefinedTags = nw.getTags().getPredefinedTags();
        for (int i = 0; i < personalTags.size(); i++) {
            Object[] parameters = null;
            final PersonalTag tag = (PersonalTag) personalTags.get(i);
            action = "insert.new.personaltag";
            parameters = new Object[2];
            parameters[0] = nw.getID();
            parameters[1] = tag.getTag();
            flag &= insertTag(action, parameters);
        }
        for (int i = 0; i < predefinedTags.size(); i++) {
            Object[] parameters = null;
            final PredefinedTag tag = (PredefinedTag) predefinedTags.get(i);
            action = "insert.new.ontologytag";
            parameters = new Object[3];
            parameters[2] = tag.getCategory();
            parameters[0] = nw.getID();
            parameters[1] = tag.getTag();
            flag &= insertTag(action, parameters);
        }
        return flag;
    }
    /**
     * Method to insert the authors of a new
     * @param nw the new data
     * @return true or false
     */
    private boolean insertNewAuthors(final New nw) {
        boolean flag = true;
        String action = "insert.new.author";
        final List e = nw.getAuthors();
        Object[] parameters = new Object[4];
        for (int i = 0; i < e.size(); i++) {
            Author a = (Author) e.get(i);
            parameters[0] = nw.getID();
            parameters[1] = a.getName();
            parameters[2] = a.getSurname();
            parameters[3] = a.getAccount();
            final DBManager dbm = grupb.upf.DBManager.impl.DBManager
                        .getInstance();
            final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                    action, parameters);
            final DBActionResult actionResult = dbm.execute(dba);
            if (!actionResult.isOk()) {
                flag &= false;
                final StringBuffer err = new StringBuffer(
                        "Error inserting the author: \n");
                if (actionResult.getErrorMsg() != null) {
                    err.append(actionResult.getErrorMsg());
                } else {
                    err.append(actionResult.getException());
                }
            }
        }
        return flag;
    }
    /**
     * Method to insert a tag to the DB.
     * @param action the action to do
     * @param parameters the parameters
     * @return true or false
     */
    private boolean insertTag(final String action, final Object [] parameters) {
        boolean flag = true;
        final DBManager dbm = grupb.upf.DBManager.impl.DBManager
                    .getInstance();
        final DBAction dba = new grupb.upf.DBManager.impl.DBAction(
                action, parameters);
        final DBActionResult actionResult = dbm.execute(dba);
        if (!actionResult.isOk()) {
            flag = false;
            final StringBuffer err = new StringBuffer(
                    "Error inserting the tags: \n");
            if (actionResult.getErrorMsg() != null) {
                err.append(actionResult.getErrorMsg());
            } else {
                err.append(actionResult.getException());
            }
        }
        return flag;
    }
}
